using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Random = UnityEngine.Random;

/// <summary>
///  四叉树计算模型，不饱和四叉树
/// </summary>
public class QuadTree : MonoBehaviour
{
    //是否有限制
    public bool islimit = false;
    // 最大分层
    [Range(1, 32)]
    public int Sample;

    // 定位点
    public Vector3 MinPoint;
    public Vector3 MaxPoint;
    
    public List<Vector3> Cache;
    // 展示队列
    public List<Vector3> ShowCache;
    public List<Node> ShowNodes;
    
    public Node root;
     
    /// <summary>
    /// 清理测试缓存
    /// </summary>
    public void ClearCache()
    {
        if (Cache == null)
            Cache = new List<Vector3>();

        Cache.Clear();
    }

    // 创建测试对象
    public void GenerateTest()
    {
        if (Cache == null)
            Cache = new List<Vector3>();
        
        var posX = Random.Range(MinPoint.x, MaxPoint.x);
        var posY = Random.Range(MinPoint.y, MaxPoint.y);
        
        Cache.Add(new Vector3(posX, posY, 0));
    }

    public void OnValidate()
    {
        StartCaculate();
    }

    private int level = 1;
    
    /// <summary>
    /// 开始计算
    /// </summary>
    public void StartCaculate()
    {
        level = 1;
        root = new Node(MinPoint, MaxPoint);
        root.level = level;
        for (int i = 0; i < Cache.Count; i++)
            root.points.Add(Cache[i]);
        
        deepNode(root);
    }

    public void deepNode(Node node)
    {
        if (Sample <= node.level)
            return;
        
        node.Grow();
        if (level < node.level)
            level = node.level;
        
        // Debug.Log("[Tree] tree level: " + level);
        
        if (node.leftdown != null)
            deepNode(node.leftdown);
        
        if (node.rightdown != null)
            deepNode(node.rightdown);
        
        if (node.leftup != null)
            deepNode(node.leftup);
        
        if (node.rightup != null)
            deepNode(node.rightup);
    }
    
    
    /// <summary>
    /// 从根节点搜索涉及区域对象
    /// </summary>
    /// <param name="center"></param>
    /// <param name="size"></param>
    public void Search(Vector3 center, Vector2 size)
    {
        if (ShowCache == null)
            ShowCache = new List<Vector3>();
        ShowCache.Clear();

        if (ShowNodes == null)
            ShowNodes = new List<Node>();
        ShowNodes.Clear();

        if (Cache == null || Cache.Count <= 0)
            return;
        
        var offsetW = size.x / 2f;
        var offsetH = size.y / 2f;
        Vector3 ld = new Vector3(center.x - offsetW, center.y - offsetH, 0);
        Vector3 rt = new Vector3(center.x + offsetW, center.y + offsetH, 0);
        Vector3 lt = new Vector3(ld.x, rt.y, 0);
        Vector3 rd = new Vector3(rt.x, ld.y, 0);
        
        var result = root.Output(ld, rt, lt, rd);
        result.ForEach(n =>
        {
            n.points.ForEach(p =>
            {
                ShowCache.Add(p);
            });
            
            ShowNodes.Add(n);
        });
    }

    /// <summary>
    /// 重置检索内容
    /// </summary>
    public void ResetSearch()
    {
        if (ShowCache != null)
            ShowCache.Clear();

        if (ShowNodes != null)
            ShowNodes.Clear();
    }
}